#ifndef __CAN_TEST_H__
#define __CAN_TEST_H__
#include <stdint.h>
#include <pthread.h>
#include <limits.h>
#include <signal.h>
#include "thread_ctrl.h"


#define CAN_ITEM_NAME           "CAN"
#define CAN_ITEM_NUM            (1 + 1)
#define CAN_ARGV_OFFSET         2
#define CAN_DRV_NAME            "pcie_can"
#define CAN_MAX_CHANNEL         16

#define CAN_MAX_BAUND_NUM       5
#define CAN_MAX_MSG_NUM         5

/*
 * CAN bit-timing parameters
 *
 * For further information, please read chapter "8 BIT TIMING
 * REQUIREMENTS" of the "Bosch CAN Specification version 2.0"
 * at http://www.semiconductors.bosch.de/pdf/can2spec.pdf.
 * include\uapi\linux\can\netlink.h
 */
struct can_bittiming {
	uint32_t bitrate;		/* Bit-rate in bits/second */
	uint32_t sample_point;	/* Sample point in one-tenth of a percent */
	uint32_t tq;			/* Time quanta (TQ) in nanoseconds */
	uint32_t prop_seg;		/* Propagation segment in TQs */
	uint32_t phase_seg1;	/* Phase buffer segment 1 in TQs */
	uint32_t phase_seg2;	/* Phase buffer segment 2 in TQs */
	uint32_t sjw;			/* Synchronisation jump width in TQs */
	uint32_t brp;			/* Bit-rate prescaler */
};

struct can_msg_t
{
    unsigned char fmt;          /* frame format, 0: Std; 1: Ext */
    unsigned char rtr;          /* frame type, 0: data frames; 1: long-range frames */
    unsigned long id;           /* can id, CAN: 0x00-0x7FF; CAN: 0x00-0x1FFFFFFF */
    unsigned char dlc;          /* data length, CAN: 0~8; CAN: 0~64 */
    unsigned char flg;          /* can flag, CAN: 0; CAN: 1 */
    unsigned char data[64];     /* payload (0-64 bytes) */
};

struct can_dev_t {
    void *parent;                                                   /* 父结构指针 */
    char name[32];                                                  /* 驱动名 */
    uint8_t index;                                                  /* 索引号 */
    int baud_rate_cnt;                                              /* 波特率数量 */
    struct can_bittiming arbitration_baud[CAN_MAX_BAUND_NUM];       /* 仲裁域波特率 */
    struct can_bittiming data_baud_rate[CAN_MAX_BAUND_NUM];         /* 数据域波特率 */
    int msg_type_cnt;                                               /* 报文种类 */
    struct can_msg_t msg[CAN_MAX_MSG_NUM];                          /* 报文 */

    char path[PATH_MAX];                                            /* 路径 */
    int fd;                                                         /* 文件 */
    struct thread_param_t *read_thread;                             /* 接收线程 */
    struct thread_param_t *write_thread;                            /* 发送线程 */
};

struct can_param_t {
    void *parent;                           /* 父结构指针 */
    char name[32];                          /* 设备名称 */
    uint8_t dev_id;                         /* 设备索引号 */
    uint8_t dev_num;                        /* 设备数量 */
    uint8_t max_num;                        /* 最大数量 */
    uint8_t type;                           /* 模块类型 */

    struct can_dev_t *dev;                  /* CAN 设备 */

    uint8_t item_id;                        /* 测试项目号 */
    uint8_t en_read;                        /* 使能接收 */
    int read_cnt;                           /* 接收数量 */
    uint8_t en_write;                       /* 使能发送 */
    int write_cnt;                          /* 发送数量 */
    int delay_ms;                           /* 延时 */
    uint8_t en_pause;                       /* 使能暂停 */
};

struct can_item_t {
    struct thread_info_t *thread;           /* thread 信息*/
    struct can_param_t *param;              /* CAN 参数 */
};

int can_test(int argc, char *argv[]);

#endif /* __CAN_TEST_H__ */
